//package com.example.demo.bean;
//
///**
// * @program: SpringAOP
// * @ClassName Test1
// * @description:
// * @author: zsn
// * @create: 2024-11-21 18:07
// * @Version 1.0
// **/
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.data.redis.core.StringRedisTemplate;
//import org.springframework.data.redis.core.ValueOperations;
//import org.springframework.stereotype.Service;
//
//import java.util.concurrent.TimeUnit;
//import java.util.concurrent.atomic.AtomicLong;
//
//@Service
//public class SequenceService {
//
//    private static final String LOCK_KEY = "sequenceLock";
//    private static final long LOCK_EXPIRE = 10; // 锁的有效时间，单位：秒
//    private static final long LOCK_WAIT_TIME = 500; // 尝试获取锁的时间间隔，单位：毫秒
//    private static final int RETRY_COUNT = 30; // 尝试获取锁的次数
//
//    private final StringRedisTemplate redisTemplate;
//    private final AtomicLong currentSequence = new AtomicLong(0);
//
//    @Autowired
//    public SequenceService(StringRedisTemplate redisTemplate) {
//        this.redisTemplate = redisTemplate;
//    }
//
//    public long generateSequence() {
//        boolean lockAcquired = false;
//        int attempt = 0;
//
//        while (attempt < RETRY_COUNT) {
//            try {
//                String result = redisTemplate.opsForValue().setIfAbsent(LOCK_KEY, "locked", LOCK_EXPIRE, TimeUnit.SECONDS);
//                if ("OK".equals(result)) {
//                    lockAcquired = true;
//                    break;
//                }
//                attempt++;
//                // 可以在这里添加日志记录尝试获取锁的次数和等待时间
//                Thread.sleep(LOCK_WAIT_TIME);
//            } catch (InterruptedException e) {
//                Thread.currentThread().interrupt();
//                // 处理中断异常，可能需要抛出或记录日志
//                break;
//            }
//        }
//
//        if (!lockAcquired) {
//            throw new RuntimeException("Unable to acquire lock after retries");
//        }
//
//        try {
//            // 使用 AtomicLong 保证线程安全地增加流水号
//            return currentSequence.incrementAndGet();
//        } finally {
//            // 释放锁，这里简单地删除键。注意：在实际应用中，应该考虑使用 Lua 脚本或 Redisson 等库来确保原子性操作。
//            // 但是，由于我们使用了 SET NX，所以即使多个客户端同时尝试删除键，也只有持有锁的客户端能够成功删除。
//            redisTemplate.delete(LOCK_KEY);
//        }
//    }
//}